using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using SmartLink.EnumLibrary;
using SmartLink.Infrastructure;
using SmartLink.Infrastructure.Cache;
using SmartLink.DTOS;

namespace SmartLink.WebApi.Filter
{
    /// <summary>
    /// Token验证
    /// </summary>
    public class TokenFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            System.Net.HttpStatusCode curStatus = System.Net.HttpStatusCode.OK;

            HttpResponseMessage tokenFailureReponse = actionContext.Request.CreateResponse(curStatus,
                                         new Results { State = StateCodeEnum.Token无效.GetHashCode(), Message = "token无效！" });

            HttpResponseMessage tokenExpireReponse = actionContext.Request.CreateResponse(curStatus,
                                         new Results { State = StateCodeEnum.Token过期.GetHashCode(), Message = "登录信息已失效，请重新登录！" });

            HttpResponseMessage KickedOutReponse = actionContext.Request.CreateResponse(curStatus,
                                         new Results { State = StateCodeEnum.Token被他人更改.GetHashCode(), Message = "您的帐号在其他地方登录，请重新登录，如非正常操作，请及时修改密码！" });

            HttpResponseMessage orgDisabledReponse = actionContext.Request.CreateResponse(curStatus,
                                         new Results { State = StateCodeEnum.Token无效.GetHashCode(), Message = "您所在的企业未启用，账户被强制下线。" });


            try
            {
                if (actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > 0
                    || actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > 0)
                {
                    return;
                }

                //没有传递token
                var headers = actionContext.Request.Headers;
                IEnumerable<string> values = null;
                var headerToken = headers.TryGetValues("token", out values);
                if (!headerToken || values == null || values.Count() == 0)
                {
                    actionContext.Response = tokenFailureReponse;
                    return;
                }

                // 1， 后台redis未取到token  2，前台传递了一个不可解的token----》   无效     3 token可解 但是 不一致 ---》 认定被踢出 
                string pageToken = values.ToList()[0];
                string redisToken = UserInfoCaches.GetRedisToken(pageToken);
                if (redisToken == null)
                {
                    actionContext.Response = tokenFailureReponse;
                    return;
                }
                else
                {
                    if (redisToken == "DecoedeError")
                    {
                        actionContext.Response = tokenFailureReponse;
                        return;
                    }
                    else
                    {
                        //token 可解 但是不一致 认定被他人踢出
                        if (pageToken != redisToken)
                        {
                            actionContext.Response = KickedOutReponse;
                            return;
                        }
                    }
                }


                //验证token时候可解 token 找不到 用户信息 认为token失效，需要重新登录
                int userId = JWTHelper.GetUserIdFromToken(pageToken);
                var userInfo = UserInfoCaches.GetUserInfoCache(userId);
                //验证是token 对应的信息存在否
                if (userInfo == null)
                {
                    actionContext.Response = tokenFailureReponse;
                    return;
                }

                //token过期验证
                var key = "UserToken_" + userId;
                DateTime expirTime = TimeHelper.GetDateTimeByUnixTime(userInfo.Expires);
                if (DateTime.Now > expirTime)
                {
                    UserInfoCaches.TokenDelete(pageToken);
                    actionContext.Response = tokenExpireReponse;
                    return;
                }




                //判断所属组织状态
                List<int> disabledCompanys = DisabledCompanysCache.GetDisabledCompanys();
                if (disabledCompanys.Contains(userInfo.OID))
                {
                    UserInfoCaches.RemoveUserInfo(userInfo.UserId);
                    actionContext.Response = orgDisabledReponse;
                    return;
                }

                //每次请求成功都更新过期时间
                UserInfoCaches.SetExpires(userId, DateTime.Now.AddSeconds(ConstData.ExpirsTimes));

            }
            catch (Exception)
            {
                actionContext.Response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.OK,
                                         new Results { State = StateCodeEnum.失败.GetHashCode(), Message = StateCodeEnum.失败.ToString() });
            }

        }
    }
}